<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link crossorigin="anonymous" rel="stylesheet" href="/cuishifeng/assets/css/githubassets-assets-frameworks.css">
    <link crossorigin="anonymous" rel="stylesheet" href="/cuishifeng/assets/css/githubassets-assets-github.css">
    <script src="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/highlight.js/10.5.0/styles/github.min.css" rel="stylesheet">
    <script>hljs.initHighlightingOnLoad();</script>
    <title>cuishifeng's wiki</title>
    <style>
        .gh-header-meta {
            padding-bottom: 16px;
            margin-top: 8px;
            font-size: 14px;
            color: #586069;
            border-bottom: 0px !important;
        }
        *{
            background-color: #F9F9F5 !important;
        }
        .bg-gray-light{
            background-color: #F9F9F5 !important;
        }
    </style>
</head><body class="logged-in env-production page-responsive intent-mouse">
<div id="app" class="application-main " data-commit-hovercards-enabled="">
    <main>
        <!-- 顶部-->
        <div id="pagehead-top" class="pagehead repohead hx_repohead readability-menu bg-gray-light pb-0 pt-0 pt-lg-5">
    <!-- d-none d-lg-flex-->
    <div class="d-flex container-lg mb-4 p-responsive d-none d-lg-flex">
        <div class="flex-auto min-width-0 width-fit mr-3">
            <h1 class="public  d-flex flex-wrap flex-items-center break-word float-none ">
                          <span class="flex-self-stretch" style="margin-top: -2px;">
                              <img id="headImage" class="avatar" alt="jonrohan" width="72" height="72"/>
                          </span>
                <span class="author ml-2 flex-self-stretch" itemprop="author">
                                <a id="webName" class="url fn" rel="author">cuishifeng's wiki</a>
                                <div id="webDesc" class="mt-2 mt-md-1 pb-3 gh-header-meta">hello åå</div>
                            </span>
            </h1>
        </div>
    </div>

</div>
        <!--内容 -->
        <transition>
            <div class=" container-lg clearfix new-discussion-timeline  p-responsive">
                <div class="repository-content ">
                    <div id="wiki-wrapper" class="page">

                        <div class="d-flex flex-column flex-md-row gh-header">
                            <h1 class="flex-auto min-width-0 mb-2 mb-md-0 mr-0 mr-md-2 gh-header-title">
                                JVM总结和G1详细分析
                            </h1>
                            <div class="mt-0 mt-lg-1 flex-shrink-0 gh-header-actions">
                                <a href="#wiki-pages-box" class="d-md-none ">Jump to bottom</a>
                            </div>
                        </div>

                        <div class="mt-2 mt-md-1 pb-3 gh-header-meta ">
                            发表于
                            <relative-time class="no-wrap">2021年4月27日</relative-time>
                            ·
                            <a class="muted-link">
                                JVM G1总结
                            </a>
                        </div>
                        <div id="wiki-content" class="mt-4">
                            <div class="gutter-condensed gutter-lg flex-column flex-md-row d-flex">
                                <div class="flex-shrink-0 col-12 col-md-9 mb-4 mb-md-0">
                                    <div id="wiki-body" class="gollum-markdown-content">
                                        <!--内容体-->
                                        <div class="markdown-body">
                                            <h3><a href="#major-gc跟full-gc是等价" id="major-gc跟full-gc是等价" class="anchor"></a>Major GC跟full GC是等价？</h3>
<ul>
  <li>yong gc、old gc、mixed gc、full gc</li>
  <li><a href="https://www.zhihu.com/question/41922036/answer/93079526">Major GC和Full GC的区别是什么？触发条件呢？ - RednaxelaFX的回答</a></li>
</ul>
<h3><a href="#heap-region-hr" id="heap-region-hr" class="anchor"></a>Heap Region (HR)</h3>
<p><img src="/images/jvm-region.png" alt="image" /></p>
<ul>
  <li>E <code>Eden</code> 新生代空间</li>
  <li>S <code>Survivor</code> 幸存区</li>
  <li>O <code>Old</code> 老年代空间</li>
  <li>
    <p>H <code>Humongous</code> 巨大对象 - 属于老年代空间</p>
  </li>
  <li>G1的分区类型 自由分区、新生代分区、老生代分区、大对象分区
    <ul>
      <li>新生代分区包含 Eden 和 Survior;</li>
      <li>大对象分区又可分为大对象头分区和大对象连续分区；</li>
    </ul>
  </li>
  <li>
    <p>Region大小</p>
    <ul>
      <li>HR的大小直接影响分配和垃圾回收效率。</li>
      <li>如果过大，一个HR可以存放多个对象，分配效率高，但是回收的时候花费时间过长；如果太小则导致分配效率低下。</li>
      <li>HR有一个上限值和下限值，取值范围从1M到32M，且是2的指数；</li>
      <li>可以通过参数 -XX:G1HeapRegionSize设定，否则会根据Heap大小自动决定；</li>
      <li>默认情况下，整个堆空间分为2048个HR（该值可以自动根据最小的堆分区大小计算得出）</li>
    </ul>
  </li>
</ul>
<h3><a href="#tlab-内存分配" id="tlab-内存分配" class="anchor"></a>TLAB 内存分配</h3>
<ul>
  <li>TLAB 全称是 thread local allocate buffer</li>
</ul>
<h3><a href="#并发标记" id="并发标记" class="anchor"></a>并发标记</h3>
<blockquote>
  <p>并发标记指的是标记线程和Mutator并发运行。那么标记线程如何并发地进行标记？正如我们前面提到的并发标记的难点，一边标记垃圾对象，一边还在生成垃圾对象。为了解决这个问题，以前的算法采用串行执行，这里的串行指的是标记工作和对象生成工作不同时进行，但在G1中引入了新的算法</p>
</blockquote>
<p><img src="/images/jvm-TAMS.png" alt="image" /></p>
<p>在堆分区中分配对象的时候，对象都是连续分配，TLAB时为了效率可以设计几个指针；</p>
<ul>
  <li>Bottom 区域中对象的末尾</li>
  <li>PrevTAMS 前一次标记时开始的的地址（TAMS指的是Top-at-Mark-Start）</li>
  <li>NextTAMS 当前开始标记时最新的地址</li>
  <li>Top 区域中对象的开头</li>
</ul>
<p>指针解决了并发标记工作内存区域的问题，还需要在引入两个额外的数据结构来记录内存标记的状态，典型的是使用位图来指示哪块内存已经使用，哪块内存还未使用；</p>
<ul>
  <li>PrevBitmap 记录PrevTAMS指针之前内存的标记状况</li>
  <li>NextBitmap 记录整个内存到NextTAMS指针之前的标记状态</li>
</ul>
<blockquote>
  <p>这里很多人都很奇怪NextBitmap包含了整个使用内存的标记状态，为什么要引入PrevBitmap这个数据结构？这个数据结构在什么时候使用？我们可以想象如果并发标记每次都成功，我们确实可以不需要PrevBitmap，只需要根据这个BitMap对对象进行清除即可。但是如果发生标记失败将会发生什么？我们将丢失上一次对Prev指针之前所有内存的标记状况，也就是说当发生失败不能完成并发标记时将需要重新标记整个内存，这显然是不对的。</p>
</blockquote>
<h3><a href="#三色标记" id="三色标记" class="anchor"></a>三色标记</h3>
<p><img src="/images/jvm-color-mark.png" alt="image" /></p>
<blockquote>
  <p>并发标记的主要问题是垃圾回收器在标记对象的过程中，Mutator可能正在改变对象引用关系图，从而造成漏标和错标。错标不会影响程序的正确性，只是造成所谓的浮动垃圾。但漏标则会导致可达对象被当做垃圾收集掉，从而影响程序的正确性。为了区别对象的不同状态，引入了三色标记法。</p>
</blockquote>
<ul>
  <li>白色：还未被垃圾回收器标记的对象</li>
  <li>灰色：自身已经被标记，但其拥有的成员变量还未被标记</li>
  <li>
    <p>黑色：自身已经被标记，且对象本身所有的成员变量也已经被标记
    <strong>两类漏标问题</strong></p>
  </li>
  <li>Mutator插入了一个从黑色对象到该白色对象的新引用，因为黑色对象已经被标记，如果不对黑色对象重新处理，那么白色对象将被漏标，造成错误。</li>
  <li>Mutator删除了所有从灰色对象到该白色对象的直接或者间接引用，因为灰色对象正在标记，字段引用的对象还没有被标记，如果这个引用的白色对象被删除了（引用发生了变化），那么这个引用对象也有可能被漏标。</li>
</ul>
<p>因此，要避免对象的漏标，只需要打破上述两个条件中的任何一个即可。所以在并发标记的时候也对应地有两种不同的实现：</p>
<ol>
  <li>增量更新算法关注对象引用插入，把被更新的黑色或者白色对象标记成灰色，打破第一个条件。</li>
  <li>SATB关注引用的删除，即在对象被赋值前，把老的被引用对象记录下来，然后根据这些对象为根重新标记一遍，打破第二个条件。</li>
</ol>
<h3><a href="#increment-update增量更新" id="increment-update增量更新" class="anchor"></a>Increment Update（增量更新）</h3>
<blockquote>
  <p>应对漏标的问题CMS使用了增量更新的方法来做；</p>
</blockquote>
<h3><a href="#satb-snapshot-at-the-beginning" id="satb-snapshot-at-the-beginning" class="anchor"></a>SATB (Snapshot-At-The-Beginning)</h3>
<p><img src="../images/jvm-SATB.png" alt="image" /></p>
<h3><a href="#jvm-调优" id="jvm-调优" class="anchor"></a>JVM 调优</h3>
<ol>
  <li>如果不符合这个规则 (大部分在 Young 的对象都不会存活很长时间)，你可能需要调整一下 Young 区域占比。来降低 Young 对象的拷贝时间。</li>
</ol>
<pre><code class="language-shell">-XX:G1NewSizePercent (默认:5) Young region 最小值
-XX:G1MaxNewSizePercent (默认: 60) Young region 最大值
</code></pre>
<ol start="2">
  <li>设置最长暂停时间目标值。</li>
</ol>
<pre><code class="language-shell">-XX:MaxGCPauseMillis=200
</code></pre>
<ol start="3">
  <li>设置年轻代最小最大值所占总堆的百分比</li>
</ol>
<pre><code class="language-shell">-XX:G1NewSizePercent=5
-XX:G1MaxNewSizePercent=60
</code></pre>
<ol start="4">
  <li>设置 STW 工作线程数的值。</li>
</ol>
<pre><code class="language-shell">-XX:ParallelGCThreads=n
</code></pre>
<ol start="5">
  <li>设置并发标记的线程数。</li>
</ol>
<pre><code class="language-shell">-XX:ConcGCThreads=n
</code></pre>

                                        </div>
                                    </div>
                                </div>
                                <!--侧边栏-->
                                <div class="flex-shrink-0 col-12 col-md-3">
                                    <div class="wiki-rightbar">
                                        <div id="wiki-pages-box" class="mb-4 wiki-pages-box js-wiki-pages-box" role="navigation">
                                            <div class="Box Box--condensed box-shadow">
                                                <div class="Box-header js-wiki-toggle-collapse" style="cursor: pointer">
                                                    <h3 class="Box-title">
                                                        <svg class="octicon octicon-triangle-down js-wiki-sidebar-toggle-display d-none"
                                                             viewBox="0 0 16 16" version="1.1" width="16" height="16"
                                                             aria-hidden="true">
                                                            <path d="M4.427 7.427l3.396 3.396a.25.25 0 00.354 0l3.396-3.396A.25.25 0 0011.396 7H4.604a.25.25 0 00-.177.427z"></path>
                                                        </svg>
                                                        <svg class="octicon octicon-triangle-right js-wiki-sidebar-toggle-display"
                                                             viewBox="0 0 16 16" version="1.1" width="16" height="16"
                                                             aria-hidden="true">
                                                            <path d="M6.427 4.427l3.396 3.396a.25.25 0 010 .354l-3.396 3.396A.25.25 0 016 11.396V4.604a.25.25 0 01.427-.177z"></path>
                                                        </svg>
                                                        Pages <span title="4" class="Counter Counter--gray ">4</span>
                                                    </h3>
                                                </div>
                                                <div class="d-none js-wiki-sidebar-toggle-display">
                                                    <div class="filter-bar">
                                                        <input type="text" id="wiki-pages-filter" class="form-control input-sm input-block js-filterable-field" placeholder="Find a Page…" aria-label="Find a Page…" autocomplete="off">
                                                    </div>
                                                    <ul class="m-0 p-0 list-style-none" data-filterable-for="wiki-pages-filter" data-filterable-type="substring" data-pjax="">
                                                        <li class="Box-row">
                                                            <strong><a class="d-block" href="/ShiFengCui/java-developer-reflection/wiki">Home</a></strong>
                                                        </li>
                                                    </ul>
                                                </div>
                                            </div>

                                        </div>

                                        <div class="gollum-markdown-content">
                                            <div class="Box Box--condensed mb-4">
                                                <div id="wiki-custom-sidebar" class="Box-body wiki-custom-sidebar markdown-body">

                                                </div>
                                            </div>
                                        </div>

                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </transition>
    </main>
</div>
<!--底部-->

<div class="footer container-lg width-full p-responsive" role="contentinfo">
    <div class="position-relative d-flex flex-row-reverse flex-lg-row flex-wrap flex-lg-nowrap flex-justify-center flex-lg-justify-between pt-6 pb-2 mt-6 f6 text-gray border-top border-gray-light ">
        <ul class="list-style-none d-flex flex-wrap col-12 col-lg-5 flex-justify-center flex-lg-justify-between mb-2 mb-lg-0">
            <li id="bottom-site-atr" class="mr-3 mr-lg-0">Â© 2021 cuishifeng.gitee.io, Inc.
                <a id="bottom-site-name" href="/">cuishifeng's wiki</a>
            </li>
        </ul>
    </div>
    <div class="d-flex flex-justify-center pb-6">
        <span class="f6 text-gray-light"></span>
    </div>
</div>
<script src="/cuishifeng/assets/js/jquery.min.js"></script>
<script src="/cuishifeng/assets/js/helper.js"></script>
<script src="/cuishifeng/data/personal-info.js"></script>
<script src="/cuishifeng/data/directory.js"></script>
</body>
</html>
